#include <GUI/Widgets/FanWidget.hpp>
#include <FL/Fl_SVG_Image.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Image_Surface.H>
#include <FL/Fl_Image.H>
#include <FL/Fl.H>
#include <FL/gl.h>
#include <FL/gl_draw.H>
#include <GUI/Theme.hpp>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>

#ifndef RESOURCE_DIR
#define RESOURCE_DIR "."
#endif

Fl_SVG_Image* FanWidget::s_fan_svg = nullptr;

static void fan_log(const char* fmt, ...)
{
#ifdef DEBUG
    va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);
#endif
}

void FanWidget::ensure_loaded()
{
    if (!s_fan_svg)
    {
        char path[512];
        std::snprintf(path, sizeof(path), "%s/fan.svg", RESOURCE_DIR);
        s_fan_svg = new Fl_SVG_Image(path);
        if (s_fan_svg->fail())
        {
            std::fprintf(stderr, "[FanWidget] 加载失败: %s\n", path);
            delete s_fan_svg;
            s_fan_svg = nullptr;
        }
    }
}

FanWidget::FanWidget(int X, int Y, int W, int H, const char* label)
    : Fl_Gl_Window(X, Y, W, H, label)
{
    ensure_loaded();
    mode(FL_ALPHA | FL_RGB | FL_DOUBLE);
}

FanWidget::~FanWidget()
{
    if (tex_id_)
    {
        glDeleteTextures(1, &tex_id_);
        tex_id_ = 0;
    }
}

void FanWidget::set_level(int lvl)
{
    if (lvl < 0) lvl = 0;
    if (lvl > 3) lvl = 3;
    level_ = lvl;
}

void FanWidget::advance()
{
    static constexpr double speed[4] = {0.0, 15.0, 44.0, 100.0};
    angle_deg_ += speed[level_];
    if (angle_deg_ >= 360.0) angle_deg_ -= 360.0;
}

void FanWidget::build_texture(int desired)
{
    if (!s_fan_svg) return;
    if (desired <= 0) return;
    if (texture_ready_ && tex_w_ == desired && tex_h_ == desired) return;

    // 光栅化到 desired*desired RGBA
    Fl_Image_Surface surf(desired, desired);
    Fl_Surface_Device::push_current(&surf);
    fl_push_clip(0, 0, desired, desired);
    fl_color(FL_WHITE); // 白底，后续把白当透明
    fl_rectf(0, 0, desired, desired);

    double sx = static_cast<double>(desired) / s_fan_svg->w();
    double sy = static_cast<double>(desired) / s_fan_svg->h();
    // 将内缩比从0.9减小到0.8，整体更小一些
    double s = std::min(sx, sy) * 0.9;
    int draw_w = static_cast<int>(s_fan_svg->w() * s);
    int draw_h = static_cast<int>(s_fan_svg->h() * s);
    int dx = (desired - draw_w) / 2;
    int dy = (desired - draw_h) / 2;
    Fl_Image* scaled = s_fan_svg->copy(draw_w, draw_h);
    if (scaled) scaled->draw(dx, dy);
    if (scaled) scaled->release();

    fl_pop_clip();
    Fl_RGB_Image* rgb = surf.image();
    Fl_Surface_Device::pop_current();
    if (!rgb) return;

    int d = rgb->d();
    if (d != 3 && d != 4)
    {
        rgb->release();
        return;
    }

    std::vector<unsigned char> rgba(desired * desired * 4, 0);
    const unsigned char* src = (const unsigned char*)rgb->data()[0];
    int stride = rgb->w() * d;
    for (int y = 0; y < desired; ++y)
    {
        const unsigned char* line = src + y * stride;
        for (int x = 0; x < desired; ++x)
        {
            const unsigned char* p = line + x * d;
            unsigned char* q = &rgba[(y * desired + x) * 4];
            q[0] = p[0];
            q[1] = p[1];
            q[2] = p[2];
            q[3] = (d == 4 ? p[3] : 255);
            // 色键透明：接近白色
            if (q[0] > 240 && q[1] > 240 && q[2] > 240) q[3] = 0;
        }
    }
    rgb->release();

    make_current();
    if (!tex_id_) glGenTextures(1, &tex_id_);
    glBindTexture(GL_TEXTURE_2D, tex_id_);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, desired, desired, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba.data());

    tex_w_ = tex_h_ = desired;
    texture_ready_ = true;
}

void FanWidget::draw()
{
    if (!valid())
    {
        glViewport(0, 0, w(), h());
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, w(), 0, h(), -1, 1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glDisable(GL_DEPTH_TEST);
    }
    // 用父容器底色或主题卡片色清屏，从而不再是白底
    Fl_Color bgc = parent() ? parent()->color() : GUI::current_theme().card_bg;
    unsigned char rr = 255, gg = 255, bb = 255;
    Fl::get_color(bgc, rr, gg, bb);
    glClearColor(rr / 255.f, gg / 255.f, bb / 255.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);

    if (!s_fan_svg) return;
    int desired = std::min(w(), h());
    if (desired <= 0) return;
    build_texture(desired);
    if (!texture_ready_) return;

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex_id_);
    glPushMatrix();
    float cx = w() / 2.0f;
    float cy = h() / 2.0f;
    glTranslatef(cx, cy, 0.f);
    glRotatef(static_cast<float>(angle_deg_), 0.f, 0.f, 1.f);
    float sz = static_cast<float>(desired) * 1.0f * 0.5f;
    glBegin(GL_QUADS);
    glTexCoord2f(0.f, 0.f);
    glVertex2f(-sz, -sz);
    glTexCoord2f(1.f, 0.f);
    glVertex2f(sz, -sz);
    glTexCoord2f(1.f, 1.f);
    glVertex2f(sz, sz);
    glTexCoord2f(0.f, 1.f);
    glVertex2f(-sz, sz);
    glEnd();
    glPopMatrix();
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
}
